﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Text;
using System.Net;
using System.Data;
using MaasOne.YahooManaged;
using MaasOne.YahooManaged.Finance;
using MaasOne.YahooManaged.Finance.API;
using System.Diagnostics;
using StockDashboard.Model;
using System.Configuration;
namespace StockDashboard.DL.Yahoo
{
    public class DALQuote
    {
        public DALQuote(String connectionString)
        {
            ConnectionString = connectionString;
        }

        public String ConnectionString { get; set; }

        public void RefreshQuotes(String symbol)
        {

            StockDashboard.Model.StockDashboardContext dc = new StockDashboard.Model.StockDashboardContext(ConnectionString);

            var qry = from s in dc.Securities
                      where s.TickerSymbol == symbol
                      select s;
            Security sec = qry.SingleOrDefault();

            if (sec == null)
            {
                sec = new Security();
                sec.TickerSymbol = symbol;
                sec.Description = symbol;
                sec.SecurityTypeID = 1;

                dc.Securities.Add(sec);
                dc.SaveChanges();
            }
            
            RefreshQuotes(dc, sec);
            
        }
        
        public void RefreshAllQuotes()
        {
            StockDashboardContext dc = new StockDashboardContext(ConnectionString);
            
            var qry = from s in dc.Securities
                      select s;


            //Get Securities
            foreach (Security sec in qry)
            {
                RefreshQuotes(dc, sec);
            }
        }

        public string GetQuoteLatest(string symbol)
        {
            String result = "";
            string urlTemplate = @"http://download.finance.yahoo.com/d/quotes.csv?s=[symbol]&f=l1c1p2&e=.csv";
            urlTemplate = urlTemplate.Replace("[symbol]", symbol);
            WebClient wc = new WebClient();
            try
            {
                result = wc.DownloadString(urlTemplate);
            }
            catch (WebException wex)
            {
                //  throw wex;
            }
            finally
            {
                wc.Dispose();
            }
            // trim off unused characters from end of line
            result = result.Replace("\r", "");

            return result;
        }

        private void RefreshQuotes(StockDashboardContext dc, Security sec)
        {
            Debug.WriteLine(System.DateTime.Now.ToShortTimeString() + ", " + sec.TickerSymbol);
            System.DateTime LastImportDate;
            if (sec.Quotes != null && sec.Quotes.Count > 0)
            {
                LastImportDate = dc.Quotes.Where(q => q.SecurityID == sec.SecurityID).Max(q => q.DateTime.DateTime1.Value);
            }
            else
            {
                LastImportDate = System.DateTime.Now.AddYears(-1);
            }
            Debug.WriteLine(System.DateTime.Now.ToShortTimeString() + ", " + sec.TickerSymbol + ", LastImportDate=" + LastImportDate.ToString("yyyyMMdd"));

            if (LastImportDate < System.DateTime.Now)
            {

                Debug.WriteLine(System.DateTime.Now.ToShortTimeString() + ", " + sec.TickerSymbol + ", From=" + LastImportDate.AddDays(1).ToString("yyyyMMdd"));
                HistQuotesDownload hqdl = new HistQuotesDownload();
                HistQuotesResponse hresp = hqdl.Download(sec.TickerSymbol, LastImportDate.AddDays(1), System.DateTime.Now, HistQuotesInterval.Daily);

                foreach (HistQuotesDataChain quotes in hresp.Result)
                {
                    foreach (HistQuoteData quote in quotes)
                    {
                        Quote q = new Quote();
                        q.SecurityID = sec.SecurityID;
                        q.DateTimeID = System.Convert.ToInt32(quote.TradingDate.ToString("yyyyMMdd"));
                        q.StartValue = System.Convert.ToDecimal(quote.Open);
                        q.EndValue = System.Convert.ToDecimal(quote.Close);
                        q.LowValue = System.Convert.ToDecimal(quote.Low);
                        q.HighValue = System.Convert.ToDecimal(quote.High);
                        q.Volume = System.Convert.ToInt64(quote.Volume);

                        dc.Quotes.Add(q);

                        Debug.WriteLine(System.DateTime.Now.ToShortTimeString() + ", " + sec.TickerSymbol + ", " + q.DateTimeID.ToString());
                    }
                }
            }

            if (System.DateTime.Now.DayOfWeek != DayOfWeek.Saturday && System.DateTime.Now.DayOfWeek != DayOfWeek.Sunday)
            {
                //Get Quote of today
                QuotesDownload qdl = new QuotesDownload();
                QuoteProperty[] qp = new QuoteProperty[]{
                                        QuoteProperty.Open, 
                                        QuoteProperty.LastTradePriceOnly,
                                        QuoteProperty.DaysLow,
                                        QuoteProperty.DaysHigh,
                                        QuoteProperty.Volume,
                                        QuoteProperty.TradeDate
                                        };
                QuotesResponse resp = qdl.Download(sec.TickerSymbol, qp);

                foreach (QuoteData quote in resp.Result)
                {
                    int dateTimeId = System.Convert.ToInt32(quote.LastTradeDate.ToString("yyyyMMdd"));
                    if (dateTimeId > 19900101)
                    {
                        bool flgNew = false;
                        Quote qd;

                        qd = dc.Quotes.FirstOrDefault(q => q.DateTimeID == dateTimeId && q.SecurityID == sec.SecurityID);

                        if (qd == null)
                        {
                            qd = new Quote();
                            flgNew = true;
                        }

                        qd.SecurityID= sec.SecurityID;
                        qd.DateTimeID = dateTimeId;
                        qd.StartValue = System.Convert.ToDecimal(quote.Open);
                        qd.EndValue = System.Convert.ToDecimal(quote.LastTradePriceOnly);
                        qd.LowValue = System.Convert.ToDecimal(quote.DaysLow);
                        qd.HighValue = System.Convert.ToDecimal(quote.DaysHigh);
                        qd.Volume = System.Convert.ToInt64(quote.Volume);

                        if (flgNew)
                            dc.Quotes.Add(qd);
                    }
                }


            }

            dc.SaveChanges();

            //Get quotes between latest and current date
            //List<QuoteInfo> quotes = GetQuotesItems(sec.TickerSymbol, LastImportDate.AddDays(1), System.DateTime.Now);

            //if (quotes != null)
            //{
            //    foreach (QuoteInfo quote in quotes)
            //    {
            //        //Insert QuoteInfo into Azure Database

            //        Quote q = new Mode.Quote();
            //        q.Security = sec;
            //        q.DateTimeID = System.Convert.ToInt32(quote.Date.ToString("yyyyMMdd"));
            //        q.StartValue = System.Convert.ToDecimal(quote.Open);
            //        q.EndValue = System.Convert.ToDecimal(quote.Close);
            //        q.LowValue = System.Convert.ToDecimal(quote.Low);
            //        q.HighValue = System.Convert.ToDecimal(quote.High);
            //        q.Volume = System.Convert.ToInt64(quote.Volume);

            //        dc.Quotes.InsertOnSubmit(q);
            //    }
            //}
        }

        public static DataTable GetQuotesTable(String symbol, System.DateTime startDate, System.DateTime endDate)
        {
            if (symbol == null || symbol.Length < 1)
                throw new ArgumentException("Symbol invalid: " + symbol);

            String history = GetHistoryFromYahooFinance(symbol, startDate, endDate);

            if (history == "") return null;

            // split to array on end of line
            string[] rows = history.Split('\n');
            // split to colums
            string[] colNames = rows[0].Split(',');


            DataTable dt = new DataTable();

            // add the columns to the DataTable
            foreach (string colName in colNames)
                dt.Columns.Add(colName);
            DataRow row = null;
            string[] rowValues;
            object[] rowItems;
            // split the rows
            for (int i = rows.Length - 1; i > 0; i--)
            {
                rowValues = rows[i].Split(',');
                row = dt.NewRow();
                rowItems = ConvertStringArrayToObjectArray(rowValues);
                if (rowItems[0] != null && (string)rowItems[0] != "")
                {
                    row.ItemArray = rowItems;
                    dt.Rows.Add(row);
                }
            }
            return dt;

        }


        public List<QuoteInfo> GetQuotesItemsXignites(string symbol, System.DateTime startDate, System.DateTime endDate)
        {
            if (symbol == null || symbol.Length < 1)
                throw new ArgumentException("Symbol invalid: " + symbol);

            String history = GetHistoryFromYahooFinance(symbol, startDate, endDate);

            if (history == "") return null;

            // split to array on end of line
            string[] rows = history.Split('\n');

            List<QuoteInfo> historyQuotesen = new List<QuoteInfo>();

            // split the rows
            QuoteInfo koersInfo;
            for (int i = rows.Length - 1; i > 0; i--)
            {
                if (rows[i] != "")
                {
                    koersInfo = new QuoteInfo(rows[i], symbol);

                    historyQuotesen.Add(koersInfo);
                }
            }
            return historyQuotesen;
        }


        public List<QuoteInfo> GetQuotesItemsYahooFinance(string symbol, System.DateTime startDate, System.DateTime endDate)
        {
            if (symbol == null || symbol.Length < 1)
                throw new ArgumentException("Symbol invalid: " + symbol);

            String history = GetHistoryFromYahooFinance(symbol, startDate, endDate);

            if (history == "") return null;

            // split to array on end of line
            string[] rows = history.Split('\n');

            List<QuoteInfo> historyQuotesen = new List<QuoteInfo>();

            // split the rows
            QuoteInfo koersInfo;
            for (int i = rows.Length - 1; i > 0; i--)
            {
                if (rows[i] != "")
                {
                    koersInfo = new QuoteInfo(rows[i], symbol);

                    historyQuotesen.Add(koersInfo);
                }
            }




            return historyQuotesen;
        }

        public static List<QuoteInfo> GetAlleQuotesItems(string symbol)
        {
            if (symbol == null || symbol.Length < 1)
                throw new ArgumentException("Symbol invalid: " + symbol);

            String history = GetHistoryFromYahooFinance(symbol, System.DateTime.MinValue, System.DateTime.MaxValue);

            if (history == "") return null;

            // split to array on end of line
            string[] rows = history.Split('\n');

            List<QuoteInfo> historyQuotesen = new List<QuoteInfo>();

            // split the rows
            QuoteInfo koersInfo;
            for (int i = rows.Length - 1; i > 0; i--)
            {
                if (rows[i] != "")
                {
                    koersInfo = new QuoteInfo(rows[i], symbol);

                    historyQuotesen.Add(koersInfo);
                }
            }
            return historyQuotesen;
        }



        private static string GetHistoryFromYahooFinance(String symbol, System.DateTime startDate, System.DateTime endDate)
        {
            String history = "";
            // NOTE: Yahoo's scheme uses a month number 1 less than actual e.g. Jan. ="0"
            int strtMo = startDate.Month - 1;
            string startMonth = strtMo.ToString();
            string startDay = startDate.Day.ToString();
            string startYear = startDate.Year.ToString();

            int endMo = endDate.Month - 1;
            string endMonth = endMo.ToString();
            string endDay = endDate.Day.ToString();
            string endYear = endDate.Year.ToString();

            string urlTemplate = "";

            if (startDate == System.DateTime.MinValue && endDate == System.DateTime.MaxValue)
            {
                urlTemplate = @"http://ichart.finance.yahoo.com/table.csv?s=[symbol]";

            }

            else
            {

                urlTemplate =
                    @"http://ichart.finance.yahoo.com/table.csv?s=[symbol]&a=" +
                      "[startMonth]&b=[startDay]&c=[startYear]&d=[endMonth]&e=" +
                         "[endDay]&f=[endYear]&g=d&ignore=.csv";

                urlTemplate = urlTemplate.Replace("[startMonth]", startMonth);
                urlTemplate = urlTemplate.Replace("[startDay]", startDay);
                urlTemplate = urlTemplate.Replace("[startYear]", startYear);

                urlTemplate = urlTemplate.Replace("[endMonth]", endMonth);
                urlTemplate = urlTemplate.Replace("[endDay]", endDay);
                urlTemplate = urlTemplate.Replace("[endYear]", endYear);

            }
            urlTemplate = urlTemplate.Replace("[symbol]", symbol);



            WebClient wc = new WebClient();
            try
            {
                history = wc.DownloadString(urlTemplate);
            }
            catch (WebException wex)
            {
                //  throw wex;
            }
            finally
            {
                wc.Dispose();
            }
            // trim off unused characters from end of line
            history = history.Replace("\r", "");

            return history;
        }



        private static object[] ConvertStringArrayToObjectArray(string[] input)
        {
            int elements = input.Length;
            object[] objArray = new object[elements];
            input.CopyTo(objArray, 0);
            return objArray;
        }



    }
}
